package cn.jdemo.juc.AQS;

import cn.jdemo.juc.AQS.alorigthm.CLH;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * ???
 * 用到了ThreadLocal类
 * 用到了AtomicReference(CAP)
 * @description
 * @date 2020/12/16
 *
 */
public class CLHLock implements Lock {
    private AtomicReference<CLHNode> tail;
    private ThreadLocal<CLHNode> threadLocal;

    /*AtomicReference<QNode> tail = new AtomicReference<QNode>(new QNode());
    ThreadLocal<QNode> myPred;
    ThreadLocal<QNode> myNode;*/

    public CLHLock(){
        this.tail = new AtomicReference<>();
        this.threadLocal = new ThreadLocal<>();
    }

    @Override
    public void lock() {
        CLHNode curNode = threadLocal.get();
        if (curNode == null){
            curNode = new CLHNode();
            threadLocal.set(curNode);
        }

        CLHNode preNode = tail.getAndSet(curNode);// 把最新节点置为尾节点
        if (preNode != null){
            while (preNode.getLocked()){
            }
        }
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
    }

    @Override
    public boolean tryLock() {
        return false;
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return false;
    }

    @Override
    public void unlock() {
        CLHNode curNode = threadLocal.get();
        threadLocal.remove();

        if(curNode == null || curNode.getLocked() == false){
            return;
        }

        if(!tail.compareAndSet(curNode, null)){
            curNode.setLocked(false);
        }
    }

    @Override
    public Condition newCondition() {
        return null;
    }

    class CLHNode {
        private volatile boolean locked = true;
        public boolean getLocked() {
            return locked;
        }
        public void setLocked(boolean locked) {
            this.locked = locked;
        }
    }
}
